package com.guochenglang.www.web.websocket;

import com.guochenglang.www.service.DialogService;
import com.guochenglang.www.service.UserService;
import com.guochenglang.www.util.MyDependency;
import com.alibaba.fastjson.JSON;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * websocket私信
 *
 * @author GuoChenglang
 */
@ServerEndpoint("/privateMessage/{username}")
public class MessageEndpoint {
    private static final UserService USER_SERVICE =MyDependency.returnObject(UserService.class);
    private static final DialogService DIALOG_SERVICE = MyDependency.returnObject(DialogService.class);

    /**
     * 所有会话集合
     */
    private static final ConcurrentHashMap<String, Session> SESSIONS = new ConcurrentHashMap<>();

    /**
     * 进入会话添加进session中
     *
     * @param session  seesion
     * @param username 会话人的键
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username) {
        SESSIONS.put(username, session);
    }

    /**
     * 关闭会话移除集合
     *
     * @param session session
     */
    @OnClose
    public void onClose(Session session) {
        SESSIONS.remove(session.getId(), session);
    }

    /**
     * 获得消息
     *
     * @param message  会话消息
     * @param username 会话的键
     */
    @OnMessage
    public void onMessage(String message, @PathParam("username") String username) throws SQLException, InterruptedException, IllegalAccessException, InstantiationException {
        //获取前端的会话对象
        Message msg = JSON.parseObject(message, Message.class);
        //获得会话的键值
        String user = msg.getUsername();
        //根据键获得会话session
        Session toSession = SESSIONS.get(user);
        System.out.println("获得消息" + msg.getContent());
        //将根据键获得的用户封装进message中
        msg.setUser(USER_SERVICE.getUser(Integer.valueOf(user)));
        //若两人正在对话
        if (toSession != null) {
            try {
                //添加已读消息
                DIALOG_SERVICE.isRead(Integer.valueOf(user), Integer.valueOf(username), msg.getContent());
                //发送消息
                toSession.getBasicRemote().sendText(JSON.toJSONString(msg));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            //添加未读消息并提醒
            DIALOG_SERVICE.noRead(Integer.valueOf(user), Integer.valueOf(username), msg.getContent());
            System.out.println("用户离线");
        }
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        throwable.printStackTrace();
    }
}
